//
//  CNDate.swift
//  Voice
//
//  Created by 卢逢卫 on 2024/3/12.
//


import Foundation

//待验证 方法名添加了 s
extension Date {
    public enum DateFormatTypes: String {
        case yearMonth_ENs = "yyyy-MM"
        case yearMonth_CNs = "yyyy年MM月"
        case yearMonthDay_ENs = "yyyy-MM-dd"
        case yearMonthDay_CNs = "yyyy年MM月dd日"
        case yearMonthDayHourMin_ENs = "yyyy-MM-dd HH:mm"
        case yearMonthDayHourMin_CNs = "yyyy年MM月dd日 HH:mm"
        case yearMonthDayHourMinSec_ENLinks
        case yearMonthDayHourMinSec_ENs = "yyyy-MM-dd HH:mm:ss"
        case yearMonthDayHourMinSec_CNs = "yyyy年MM月dd日 HH:mm:ss"
        case HourMins                   = "HH:mm"
        case HourMinSecs                = "HH:mm:ss"
    }
    //ok
    public static func cn_getDateStrFrom(date: Date, dateFormat: DateFormatTypes) -> String? {

        let formatter = DateFormatter()
            formatter.dateFormat = dateFormat.rawValue
            formatter.timeZone = TimeZone(identifier: "UTC") // 设置为协调世界时 (UTC)
            formatter.locale = Locale(identifier: "en_US_POSIX")
//
            let adjustedDate = date.addingTimeInterval(TimeInterval(TimeZone.current.secondsFromGMT() - TimeZone(identifier: "UTC")!.secondsFromGMT()))
            return formatter.string(from: adjustedDate)
        
//        let formatter = DateFormatter()
//        var formatString = dateFormat.rawValue
//            formatString = formatString.replacingOccurrences(of: "a", with: "")
//            
//            formatter.dateFormat = formatString
//            formatter.locale = Locale(identifier: "en_US_POSIX")// 使用当前时区
//            
//            return formatter.string(from: date)
        
    }
    
    //ok
    public static func cn_getDateFrom(dateStr: String, dateFormat: DateFormatTypes) -> Date? {
//        let formatter = DateFormatter()
//        formatter.dateFormat = dateFormat.rawValue
//        return formatter.date(from: dateStr)
        let formatter = DateFormatter()
            formatter.dateFormat = dateFormat.rawValue
            formatter.timeZone = TimeZone(identifier: "UTC") // 设置为协调世界时 (UTC)
            return formatter.date(from: dateStr)
    }

    public static func cn_getDateFrom(date: Date, dateFormat: DateFormatTypes) -> Date? {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat.rawValue
        let dateString = formatter.string(from: date)
        return formatter.date(from: dateString)
    }

    public static func cn_getTimeStampFrom(date: Date) -> Int {
        return Int(date.timeIntervalSince1970)
    }
    
    //没有用到
    public static func cn_getTimeStampFrom(dateStr: String, dateFormat: DateFormatTypes) -> Int {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat.rawValue
        if let date = formatter.date(from: dateStr) {
            return Int(date.timeIntervalSince1970)
        }
        return 0
    }
    
    //没有用到
    public static func cn_getDateStrFrom(timeStamp: String, dateFormat: DateFormatTypes) -> String {
        guard let timeStampInt = Int(timeStamp) else {
            return ""
        }
        let date = Date(timeIntervalSince1970: TimeInterval(timeStampInt))
        return cn_getDateStrFrom(date: date, dateFormat: dateFormat) ?? ""
    }

    public static func cn_getDateFrom(timeStamp: String) -> Date {
        guard let timeStampInt = Int(timeStamp) else {
            return Date()
        }
        return Date(timeIntervalSince1970: TimeInterval(timeStampInt))
    }
}

extension Date {
    public var cn_year: Int {
        let calendar = Calendar.current
        return calendar.component(.year, from: self)
    }

    public var cn_month: Int {
        let calendar = Calendar.current
        return calendar.component(.month, from: self)
    }

    public var cn_day: Int {
        let calendar = Calendar.current
        return calendar.component(.day, from: self)
    }

    public var cn_hour: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH"
        return formatter.string(from: self)
    }

    public var cn_min: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "mm"
        return formatter.string(from: self)
    }

    public var cn_sec: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "ss"
        return formatter.string(from: self)
    }

//    public var cn_weekDay: Int {
//        let calendar = Calendar.current
//        return calendar.component(.weekday, from: self)
//    }

    public var cn_monthDays: Int {
        let calendar = Calendar.current
        let range = calendar.range(of: .day, in: .month, for: self)
        return range?.count ?? 0
    }

    public var cn_monthFirstDayisWeek: Int {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month], from: self)
        let firstDayOfMonth = calendar.date(from: components)
        return calendar.component(.weekday, from: firstDayOfMonth ?? self)
    }

    public var cn_nextMonthLastDayDates: String {
        var calendar = Calendar(identifier: .gregorian)
        calendar.timeZone = TimeZone(identifier: "Asia/Shanghai")! // 设置为东八区时区
        
        var components = DateComponents()
        components.month = 2 // 将月份增加为2，以获取下一个月
        components.day = -1
        
        let nextMonthFirstDay = calendar.date(byAdding: components, to: self)
        
        let nextMonth = calendar.date(byAdding: DateComponents(month: 1), to: nextMonthFirstDay ?? self)
        let nextMonthLastDay = calendar.date(byAdding: DateComponents(day: -1), to: nextMonth ?? self)
        
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter.string(from: nextMonthLastDay ?? self)
    }

    public func cn_isToday() -> Bool {
        let calendar = Calendar.current
        return calendar.isDateInToday(self)
    }
}

extension Date {
    public static func cn_isTime_12hour() -> Bool {
        let formatter = DateFormatter()
        formatter.dateFormat = "a"
        let amPM = formatter.string(from: Date())
        return amPM.lowercased() == "am" || amPM.lowercased() == "pm"
    }

    public static var cn_currentDate: Date {
//        let timeZoneOffset = TimeInterval(TimeZone.current.secondsFromGMT())
//        let currentDate = Date(timeIntervalSinceNow: timeZoneOffset)
        return Date()
    }

    public static var cn_currentTimeStamp: Int {
        let currentTimeStamp = Int(Date().timeIntervalSince1970)
        return currentTimeStamp
    }

    public static func cn_getCurrentTimeStr(dateFormat: Date.DateFormatTypes) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat.rawValue
        let currentTimeStr = formatter.string(from: Date())
        return currentTimeStr
    }
}

extension Date {
    public static func cn_getMonthDays(year: String, month: String) -> Int {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM"
        guard let date = formatter.date(from: "\(year)-\(month)") else { return 0 }
        let calendar = Calendar.current
        let range = calendar.range(of: .day, in: .month, for: date)
        return range?.count ?? 0
    }

    public static func cn_getMonthFirstDayisWeek(year: String, month: String) -> Int {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM"
        guard let date = formatter.date(from: "\(year)-\(month)") else { return 0 }
        let calendar = Calendar.current
        let components = calendar.dateComponents([.year, .month], from: date)
        let firstDayOfMonth = calendar.date(from: components)
        return calendar.component(.weekday, from: firstDayOfMonth ?? date)
    }

    public static func cn_getDaysBetweenDate(fromeDate: String, toDate: String) -> Int {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        guard let fromDate = formatter.date(from: fromeDate), let toDate = formatter.date(from: toDate) else { return 0 }
        return cn_getDaysBetweenDate(fromeDate: fromDate, toDate: toDate)
    }

    public static func cn_getDaysBetweenDate(fromeDate: Date, toDate: Date) -> Int {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.day], from: fromeDate, to: toDate)
        return components.day ?? 0
    }

    public static func cn_getHoursBetweenDate(fromeDate: Date, toDate: Date) -> Int {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.hour], from: fromeDate, to: toDate)
        return components.hour ?? 0
    }

    public static func cn_getMinutesBetweenDate(fromeDate: Date, toDate: Date) -> Int {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.minute], from: fromeDate, to: toDate)
        return components.minute ?? 0
    }

    public static func cn_getSecondsBetweenDate(fromeDate: Date, toDate: Date) -> Int {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.second], from: fromeDate, to: toDate)
        return components.second ?? 0
    }

    public func cn_compareBetweenDate(otherDate: Date) -> ComparisonResult {
        return self.compare(otherDate)
    }
}

extension Date {
    public static func cn_add0BeforeNumber(number: Int) -> String {
        return String(format: "%02d", number)
    }

    public static func cn_getMonthFrom(num: Int) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMMM"
        guard let month = Calendar.current.date(byAdding: .month, value: num - 1, to: Date()) else { return "" }
        return formatter.string(from: month)
    }

    public static func cn_getAgoTextFromNow(dateStr: String, dateFormat: Date.DateFormatTypes) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat.rawValue
        guard let date = formatter.date(from: dateStr) else { return "" }

        let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date, to: Date())

        if let year = components.year, year > 0 {
            return "\(year)年前"
        } else if let month = components.month, month > 0 {
            return "\(month)个月前"
        } else if let day = components.day, day > 0 {
            return "\(day)天前"
        } else if let hour = components.hour, hour > 0 {
            return "\(hour)小时前"
        } else if let minute = components.minute, minute > 0 {
            return "\(minute)分钟前"
        } else if let second = components.second, second > 0 {
            return "\(second)秒前"
        } else {
            return "刚刚"
        }
    }

    public static func cn_getNewDateByAdding(yearNum: Int, monthNum: Int, dayNum: Int) -> Date? {
        let calendar = Calendar.current
        var dateComponents = DateComponents()
        dateComponents.year = yearNum
        dateComponents.month = monthNum
        dateComponents.day = dayNum
        return calendar.date(byAdding: dateComponents, to: Date())
    }
}


extension Date {
    var cn_weekDay: Int {
        let calendar = Calendar.current
        let weekDay = calendar.component(.weekday, from: self)
        return weekDay
    }
}
